package DataFile;

import java.nio.ByteBuffer;
import java.util.LinkedList;

import ClassData.MethodInfo;

/**
 * 
 * @note rewritten by Dominik Ollesz
 */
public class Structure_MethodTable extends Structure_Template {

	private LinkedList<Structure_MethodData> methodTable = 
		new LinkedList<Structure_MethodData>() ;  
		
	public Structure_MethodTable(MethodInfo[] methods) {
		for (MethodInfo methodinfo : methods) {
			methodTable.add(new Structure_MethodData(methodinfo));
		}
	}

	protected int setBaseAddress(int newBaseAdress) {
		while ((newBaseAdress%4)!=0) {
			newBaseAdress++;
		}
		
		baseAdress=newBaseAdress;
		return(baseAdress+getMemorySize());
	}

	/**
	 * @return Elements inside Table.
	 */
	public int size() {
		return(methodTable.size());	
	}

	public Structure_MethodData get(int index) {
		return(methodTable.get(index));
	}

	/**
	 * <table>
	 *   <thead><tr><th>Attribute</th><th>Symbolic value</th><th>Bytes</th></tr></thead>
	 *   <tbody>
	 *   <tr> <td>Fields count</td>             <td>SIZE_FIELD_WIDTH</td>  <td>4</td> </tr>
	 *   <tr> <td>AccessFlags</td>              <td>n*Address_WIDTH</td>   <td>n*4</td> </tr>
	 *   <tr> <td></td>                         <td></td>              <td><b>4+n*4</b></td></tr>
	 *   </tbody>
	 * </table>
	 */
	protected int getMemorySize() {
		int mySize;
		
		mySize =SIZE_FIELD_WIDTH; // fields count
		mySize =SIZE_FIELD_WIDTH; // 
		mySize+=(methodTable.size()*ADRESS_WIDTH);
		
		return(mySize);
	}

	protected String getMemoryMapAsString() {
		String returnString;
	
		returnString="\nMethod Table : Base Adress - ";
		returnString+=getAdressAsHexString(baseAdress);
		returnString+=" : size - "+getMemorySize();
		//returnString+=" name Index : "+myClassInfo.GetNameIndex();
		returnString+="\n";
	
		return(returnString);
	}

	/**
	 *  writes data into memory file
	 *  @author Tavin
	 *  @param fileData buffer for data
	 *  @note changed by Dominik Ollesz 
	 */
	public void writeData(ByteBuffer fileData) {
		fileData.position(baseAdress-DataFileCreator.BASE_MEMORY_ADRESS);
		
		fileData.putShort((short)methodTable.size());          //  2 Bytes: Size
		fileData.putShort((short)0);                           //  2 Bytes: Dummy

		for (Structure_MethodData methoddata : methodTable) {  // Size x
			fileData.putInt(methoddata.getBaseAddress());      //  4 Bytes: Address
		}                                                      //-------------------
                                                               //  4 Bytes * (Size+1)
		for (Structure_MethodData methoddata : methodTable) {
			methoddata.writeData(fileData);
		}
		
	}


}
